#include <memory>
#include <vector>
#include "udpServer.hpp"

static void Usage(const std::string &proc)
{
    std::cout << "Usage\n"
              << proc << " serverport" << std::endl;
}

std::string Handle(const std::string &message, struct sockaddr_in client)
{
    std::string recvdata;
    const char *clientip = inet_ntoa(client.sin_addr);
    uint16_t clientport = ntohs(client.sin_port);
    recvdata += "[";
    recvdata += clientip;
    recvdata += ":";
    recvdata += std::to_string(clientport);
    recvdata += "]";
    recvdata += message;

    return recvdata;

    // pid_t id = fork();
    // if(id == 0)
    // {
    //     // ls -a -l -> "ls" "-a" "-l"
    //     // exec(*)
    //     // 最后将结果放到字符串当中
    // }
}

bool SafeCheck(const std::string& cmd)
{
    int safe = false;
    std::vector<std::string> key_word = {
        "mv",
        "rm",
        "cp",
        "kill",
        "unlink",
        "apt"
    };

    for(auto& word : key_word)
    {
        auto pos = cmd.find(word);
        if(pos != std::string::npos) return false;
    }

    return true;
}

std::string ExecuteCommand(const std::string &message, struct sockaddr_in client)
{
    // popen函数。把你要执行的命令直接以字符串形式给我，popen底层创建子进程，让父子进程建立管道，
    // 然后让子进程进行程序替换把他的运行结果通过管道返回给调用方，调用方可以通过文件指针的方式读取。
    if(!SafeCheck(message)) return "Bad command";
    FILE* fp = popen(message.c_str(), "r");
    if(nullptr == fp)
    {
        perror("popen");
        return "error";
    }
    std::string result;
    char buffer[4096];
    while(1)
    {
        char* res = fgets(buffer, sizeof(buffer), fp);
        if(res == nullptr)
        {
            break;
        }
        result += buffer;
    }
    pclose(fp);

    return result;
}

int main(int argc, char **argv)
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(USAGEERROR);
    }
    uint16_t serverport = std::stoi(argv[1]);
    std::unique_ptr<UdpServer> svr(new UdpServer(serverport));
    svr->init();
    svr->start();
    // svr->start(Handle);
    // svr->start(ExecuteCommand);
    return 0;
}